package com.xuecheng.service.impl;

import com.alibaba.fastjson.JSON;
import com.xuecheng.mapper.XcMenuMapper;
import com.xuecheng.model.dto.AuthParamsDTO;
import com.xuecheng.model.po.XcMenu;
import com.xuecheng.model.vo.XcUserExtVO;
import com.xuecheng.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;


@Slf4j
@Service
public class UserServiceImpl implements UserDetailsService {
	
	@Resource
	private ApplicationContext applicationContext;
	@Resource
	private XcMenuMapper xcMenuMapper;
	
	//传入的是AuthParamsDto的json串
	@Override
	public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
		AuthParamsDTO authParamsDto = null;
		try {
			//将认证参数转为AuthParamsDto类型
			authParamsDto = JSON.parseObject(s, AuthParamsDTO.class);
		} catch (Exception e) {
			log.info("认证请求不符合项目要求:{}", s);
			throw new RuntimeException("认证请求数据格式不对");
		}
		//认证方式,
		String authType = authParamsDto.getAuthType();
		//从spring容器中拿具体的认证bean实例
		AuthService authService = applicationContext.getBean(authType + "_authservice", AuthService.class);
		//开始认证,认证成功拿到用户信息
		XcUserExtVO xcUserExtVO = authService.execute(authParamsDto);
		
		return getUserPrincipal(xcUserExtVO);
	}
	//根据XcUserExt对象构造一个UserDetails对象
	
	/**
	 * 查询用户信息
	 */
	public UserDetails getUserPrincipal(XcUserExtVO user) {
		
		//权限列表，存放的用户权限
		List<String> permissionList = new ArrayList<>();
		
		//根据用户id查询数据库中他的权限
		List<XcMenu> xcMenus = xcMenuMapper.selectPermissionByUserId(user.getId());
		xcMenus.forEach(menu -> {
			permissionList.add(menu.getCode());
		});
		if (permissionList.isEmpty()) {
			//用户权限,如果不加报Cannot pass a null GrantedAuthority collection
			permissionList.add("test");
		}
		
		String[] authorities = permissionList.toArray(new String[0]);
		//原来存的是账号，现在扩展为用户的全部信息(密码不要放)
		user.setPassword(null);
		String jsonString = JSON.toJSONString(user);
		
		return User.withUsername(jsonString).password("").authorities(authorities).build();
	}
	
}
